package com.example.demo.synchronizationDemo;

import java.util.concurrent.*;

/**
 * Created by 蔡超 on 2018/10/10.
 */
public class Demo2 {
    
    /** 
    * @Description: 同时执行
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 9:02
     *
     * A print 0
        B print 0
        A print 1
        B print 1
        A print 2
        B print 2
    */
    public static void m1(){
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    print("A");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    print("B");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();

    }

    /** 
    * @Description: join 按照顺序执行
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 9:01
     *
     *  A print 0
        A print 1
        A print 2
        B print 0
        B print 1
        B print 2
    */
    public static void m2(){
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    print("A");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                    print("B");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();
    }

    public static void print(String name) throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            Thread.sleep((long) (Math.random()*1000));
            System.out.println(name + " print " + i);
        }
    };

    /** 
    * @Description: A执行1，然后等B执行完，再执行A剩下的
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 9:04
    */
    public static void m3(){

        Object lock = new Object();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("A1");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("A2");
                    System.out.println("A3");
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock){
                    System.out.println("B1");
                    System.out.println("B2");
                    System.out.println("B3");
                    lock.notify();
                }
            }
        });

        t1.start();
        t2.start();
    }




    /** 
    * @Description:
     * 四个线程 A B C D，其中 D 要等到 A B C 全执行完毕后才执行，而且 A B C 是同步运行的
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 9:18
    */
    public static void m4(){
        int NUM = 3;

        CountDownLatch countDownLatch = new CountDownLatch(NUM);

        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行D。。。。。。。。。。");
            }
        });

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行A。。。。。。。。。。");
                countDownLatch.countDown();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行B。。。。。。。。。。");
                countDownLatch.countDown();
            }
        });

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行C。。。。。。。。。。");
                countDownLatch.countDown();
            }
        });


        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
    
    
    /** 
    * @Description:  三个运动员各自准备，等到三个人都准备好后，再一起跑
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 9:41
    */
    public static void m5(){
        CyclicBarrier cyc = new CyclicBarrier(3);

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("A准备完毕。。。。。。。。。。");
                try {
                    cyc.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("A已执行。。。。。。。。。。");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("B准备完毕。。。。。。。。。。");
                try {
                    cyc.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("B已执行。。。。。。。。。。");
            }
        });

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("C准备完毕。。。。。。。。。。");
                try {
                    cyc.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("C已执行。。。。。。。。。。");
            }
        });


        t1.start();
        t2.start();
        t3.start();

    }

    /** 
    * @Description: 获取线程返回值
    * @Param:  
    * @return:  
    * @Author: 蔡超
    * @Date: 2018/10/10 10:11
    */
    public static void m6(){
        Callable<Integer> cal = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("task status");
                Integer integer = 0;
                for (int i = 0; i < 100; i++) {
                    integer = integer + i;
                }
                System.out.println("task finish");
                return integer;
            }
        };

        FutureTask<Integer> futureTask = new FutureTask<Integer>(cal);
        new Thread(futureTask).start();
        try {
            System.out.println("before......");
            Integer result = futureTask.get();
            System.out.println("result: " + result);
            System.out.println("after.......");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
//        Demo2.m1();
        Demo2.m2();
//        Demo2.m3();
//        Demo2.m4();
//        Demo2.m5();
//        Demo2.m6();
    }

}
